home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
CRS
/
crs55.d81
/
cdi.c
< prev
next >
Wrap
Text File
|
2009-10-10
|
5KB
|
264 lines
/*
* CDI.C - CHARACTER DIFFERENCE DETECTOR
*
* ┴DRIAN ╨EPPER, 1987
*
* DEVELOPED WITH/FOR ├ ╨╧╫┼╥ 64 SYSTEM
*
* ╒PLOADED AS IS, IN RESPONSE TO
* PERCEIVED NEED. (╘HAT'S AN APOLOGY
* FOR LACK OF COMMENTS)
*
* ╒SAGE:
*
* CDI [-H -O# -L# -M#] FILE1 FILE2
*
* -H GIVE OUTPUT IN HEX (ELSE DECIMAL)
*
* -O SPECIFY AN OFFSET (IN DECIMAL) TO
* BE ASSUMED FOR BEGINNING OF FILE
*
* -L,-M SET VALUES OF VARS MATLEN,
* AND MATRAT, WHICH INFLUENCE THE
* ALGORITHM FOR DECIDING WHEN FILES
* ARE MATCHING AGAIN
*/
#INCLUDE <STDIO.H>
#DEFINE ┘┼╙ 1
#DEFINE ╬╧ 0
TYPEDEF INT ┬╔╟; /* USE FLOAT FOR REALLY ┬╔╟ FILES */
INT MATLEN = 20;
INT MATRAT = 2;
INT HEX = 0;
INT OFFSET = 0;
MAIN(ARGC,AV)
INT ARGC;
CHAR **AV;
█
AUTO ╞╔╠┼ F1, F2;
AUTO CHAR **ARGV;
ARGV = AV;
ARGC = OPTION(ARGC, &ARGV);
IF (ARGC < 2) █
PRINTF("USAGE:CDI [-L# -M# -H -O#] FILE1 FILE2\N");
EXIT(1);
▌
IF ((F1 = FOPEN(ARGV[0], "R")) == 0 ▀▀
FERROR()) █
PRINTF("CAN'T OPEN %S\N",ARGV[0]);
EXIT(1);
▌
IF ((F2 = FOPEN(ARGV[1], "R")) == 0 ▀▀
FERROR()) █
PRINTF("CAN'T OPEN %S\N",ARGV[1]);
EXIT(1);
▌
CDI(F1, F2, ARGV[0], ARGV[1]);
▌
OPTION(ARGC, PARGV)
INT ARGC;
CHAR ***PARGV;
█
AUTO CHAR **ARGV;
MATLEN = 20;
MATRAT = 2;
HEX = 0;
OFFSET = 0;
ARGV = *PARGV;
++ARGV;
--ARGC;
WHILE (ARGC > 0 && *ARGV[0] == '-') █
SWITCH ((*ARGV)[1])
█
CASE 'L':
IF (--ARGC < 1 ▀▀ (MATLEN = ATOI(*++ARGV)) <= 0)
MATLEN = 1;
BREAK;
CASE 'M':
IF (--ARGC < 1 ▀▀ (MATRAT = ATOI(*++ARGV)) <= 0)
MATRAT = 1;
BREAK;
CASE 'O':
IF (--ARGC >= 1)
OFFSET = ATOI(*++ARGV);
BREAK;
CASE 'H':
HEX = 1;
BREAK;
DEFAULT:
*PARGV = ARGV;
RETURN 0;
▌
--ARGC;
++ARGV;
▌
*PARGV = ARGV;
RETURN ARGC;
▌
BCMP(B1, B2, LEN)
INT B1[], B2[];
INT LEN;
█
AUTO INT I;
FOR (I = 0; I < LEN; ++I)
IF (B1[I] != B2[I]) RETURN ╬╧;
RETURN ┘┼╙;
▌
MATCH(U1, B1, R1, U2, B2, R2, LENGTH)
INT U1;
INT B1[];
INT R1;
INT U2;
INT B2[];
INT R2;
INT LENGTH;
█
AUTO INT I;
IF ((R1-U1) < LENGTH ▀▀ (R2-U2) < LENGTH) RETURN R1;
FOR (I = U1; I <= (R1-LENGTH) && BCMP(&B1[I], &B2[R2-LENGTH], LENGTH) == ╬╧; ++I)
;
RETURN I;
▌
SHUFFLE(BUF, R, U)
INT BUF[];
INT R, U;
█
AUTO INT I;
IF (U == 0) █
PRINTF("╘OO MANY DIFFERENCES\N");
EXIT(1);
▌
FOR (I = U; I < R; ++I)
BUF[I-U] = BUF[I];
RETURN R-U;
▌
#DEFINE ═┴╪┬╒╞ 1000
INT BUF1[═┴╪┬╒╞] = █0▌;
INT BUF2[═┴╪┬╒╞] = █0▌;
CDI(F1, F2, NAME1, NAME2)
╞╔╠┼ F1, F2;
CHAR *NAME1, *NAME2;
█
AUTO ┬╔╟ COUNT1, COUNT2;
AUTO INT USED1, USED2; /* BUFFERED CHAR "USED" */
AUTO INT READ1, READ2; /* BUFFERED CHAR "READ" */
AUTO INT I1, I2;
AUTO INT LEN;
AUTO CHAR *FMT;
READ1 = READ2 = 0;
USED1 = USED2 = 0;
COUNT1 = COUNT2 = ((┬╔╟)OFFSET);
FOR ( ; ; ) █
WHILE (USED1 != READ1 ▀▀ USED2 != READ2) █
IF (USED1 == READ1) █
USED1 = READ1 = 0;
BUF1[READ1++] = GETC(F1);
▌
IF (USED2 == READ2) █
USED2 = READ2 = 0;
BUF2[READ2++] = GETC(F2);
▌
LEN = READ1-USED1;
IF ((READ2-USED2) > LEN) LEN = READ2-USED2;
LEN = (LEN/MATRAT) + 1;
IF (LEN > MATLEN) LEN = MATLEN;
I1 = MATCH(USED1, BUF1, READ1, USED2, BUF2, READ2, LEN);
I2 = MATCH(USED2, BUF2, READ2, USED1, BUF1, READ1, LEN);
/* ASSERT USED1 < READ1 && USED2 < READ2 */
IF (BUF1[USED1] == BUF2[USED2]) █
++USED1;
++USED2;
COUNT1 = COUNT1 + ((┬╔╟)1);
COUNT2 = COUNT2 + ((┬╔╟)1);
▌
ELSE IF (I1 <= (READ1-LEN) && (I2 > (READ2-LEN) ▀▀ (I1-USED1) <= (I2-USED2))) █
SHOWDIFF(&COUNT1, BUF1, &USED1, I1, &COUNT2, BUF2, &USED2, READ2-LEN, LEN);
▌
ELSE IF (I2 <= (READ2-LEN) && (I1 > (READ1-LEN) ▀▀ (I2-USED2) <= (I1-USED1))) █
SHOWDIFF(&COUNT1, BUF1, &USED1, READ1-LEN, &COUNT2, BUF2, &USED2, I2, LEN);
▌
ELSE █
IF (READ1 >= ═┴╪┬╒╞) █
READ1 = SHUFFLE(BUF1, READ1, USED1);
USED1 = 0;
▌
BUF1[READ1++] = GETC(F1);
IF (READ2 >= ═┴╪┬╒╞) █
READ2 = SHUFFLE(BUF2, READ2, USED2);
USED2 = 0;
▌
BUF2[READ2++] = GETC(F2);
▌
▌
USED1 = READ1 = 0;
BUF1[0] = GETC(F1);
USED2 = READ2 = 0;
BUF2[0] = GETC(F2);
IF (BUF1[0] == ┼╧╞ && BUF2[0] == ┼╧╞) BREAK;
IF (BUF1[0] != BUF2[0]) █
++READ1;
++READ2;
▌
ELSE █
COUNT1 = COUNT1 + ((┬╔╟)1);
COUNT2 = COUNT2 + ((┬╔╟)1);
▌
▌
FMT = "%D:%S %0.0F(%0.0F BYTES)\N";
IF (SIZEOF(┬╔╟) != SIZEOF(FLOAT))
FMT = HEX ? "%D:%S $%04X (%D BYTES)\N" : "%D:%S %D (%D BYTES)\N";
PRINTF(FMT, 1, NAME1, COUNT1, COUNT1-((┬╔╟)OFFSET));
PRINTF(FMT, 2, NAME2, COUNT2, COUNT2-((┬╔╟)OFFSET));
▌
SHOWDIFF(PC1, B1, PU1, I1, PC2, B2, PU2, I2, LEN)
┬╔╟ *PC1;
INT B1[];
INT *PU1;
INT I1;
┬╔╟ *PC2;
INT B2[];
INT *PU2;
INT I2;
█
AUTO INT I;
AUTO CHAR *FMT;
FMT = "%D:(%6.0F):";
IF (SIZEOF(┬╔╟) != SIZEOF(FLOAT))
FMT = HEX ? "%D:($%04X):" : "%D:(%6D):";
IF (B1[I1+LEN-1] != B2[I2+LEN-1]) █
PRINTF("SHOULDN'T HAPPEN\N");
▌
PRINTF(FMT, 1, *PC1);
FOR (I = *PU1; I <= I1; ++I)
PRINTF(" %02X", B1[I]);
PRINTF("\N");
PRINTF(FMT, 2, *PC2);
FOR (I = *PU2; I <= I2; ++I)
PRINTF(" %02X", B2[I]);
PRINTF("\N");
*PC1 = *PC1 + ((┬╔╟)(I1 - *PU1 + 1));
*PU1 = I1 + 1;
*PC2 = *PC2 + ((┬╔╟)(I2 - *PU2 + 1));
*PU2 = I2 + 1;
▌